﻿using System;
using System.Data;
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.IO;
using System.Text;


[Serializable]
[SqlUserDefinedAggregate(Format.UserDefined, IsInvariantToNulls = true, IsInvariantToDuplicates = false, IsInvariantToOrder = true, MaxByteSize = -1)]
public class NthAgg : IBinarySerialize
{
    private StringBuilder recs_buffer;
    private Int64 recs_cnt;

    // Initialize the internal variables
    public void Init()
    {
        this.recs_buffer = new StringBuilder();
        this.recs_cnt = 0;
    }

    // check for specified record , not if the value is null
    public void Accumulate(SqlString rec_value, SqlInt64 rec_no)
    {

        this.recs_cnt = this.recs_cnt + 1;

        if (rec_value.IsNull)
        { 
            return;
        }

        if (rec_no == recs_cnt)
        {
            this.recs_buffer.Append(rec_value.Value);
            return; 
        }
    }

    // Merge the partially computed aggregate with this aggregate.
    public void Merge(NthAgg other)
    {
        this.recs_buffer.Append(other.recs_buffer);
    }

    // Called at the end of aggregation, to return the results of the aggregation.
    public SqlString Terminate()
    {
        string output = string.Empty;
        if (this.recs_buffer != null && this.recs_buffer.Length > 0)
            {
            output = this.recs_buffer.ToString();
            }
        else
            output = null;

        return new SqlString(output);
    }

    public void Read(BinaryReader r)
    {
        recs_buffer = new StringBuilder(r.ReadString());
    }

    public void Write(BinaryWriter w)
    {
        w.Write(this.recs_buffer.ToString());
    }
}
